<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>数据和虚拟dom的结合</title>
	<link rel="stylesheet" href="">
</head>
<body>
	<div id="app">
        <h1>{{ list.age[0][0] }}</h1>
        <p>{{ list.age[2] }}</p>
        <ul>
            <li>{{ list.name.na }}</li>
            <li>{{ list.name.na }}</li>
            <li>{{ list.age[1] }}</li>
        </ul>
    </div>
</body>
<script src="004.js"></script>
<script src="006.js"></script>
<script>
	
	class CHVue {
		constructor(option) {
			this._el = document.querySelector(option.el);
			this._data = option.data;
			this._parent = this._el.parentNode;

			this.mount();	// 挂载
		}

		mount() {
			// 1. 该render方法的作用是产生一个具有缓存作用的虚拟dom
			this.render = this.createRenderFn();
			this.mountComponent();
		}

		mountComponent() {
			this.update(this.render());
		}

		// 创造一个render方法，目的是为了缓存虚拟dom
		createRenderFn() {
			let vnode = createNode(this._el);

			// 将数据和vnode合并
			return function() {
				this.createNodeByData(vnode);
				return vnode;
			}
		}

		// 将虚拟dom渲染为真实的dom， vue使用了diff算法
		update(vnode) {
			let dom = this.createDom(vnode);
			this._parent.appendChild(dom);
		}

		// 将数据和带坑的虚拟dom结合起来
		createNodeByData(vnode) {
			let children = vnode.children;

			for(let i = 0; i < children.length; i++) {
				let type = children[i].type;

				if(type === 1) {
					this.createNodeByData(children[i]);
				} else if(type === 3) {
		            let value = children[i].value;
					value = value.replace(/\{\{(.*?)\}\}/g, (_, g)=>{
		                return getPathData(this._data, g);
		            })
					children[i].value = value;
				}
			}
		}

		// 将虚拟的dom转换为真实的dom
		createDom(vnode) {
			let dom;	// 真实的dom
			let type = vnode.type;

			if(type === 1) {
				let data = vnode.data;
				let children = vnode.children;
				dom = document.createElement(vnode.name);

				// 遍历属性值
				data.forEach(val=>{
					let key = Object.keys(val);
					dom.setAttribute(key, val[key]);
				});

				// 使用递归函数创建子元素
				for(let i = 0; i < children.length; i++) {
					dom.appendChild(this.createDom(children[i]));
				}
			} 
			else if(type === 3) {
				dom = document.createTextNode(vnode.value);
			}

			return dom;
		}
	}


	let app = new CHVue({
		el: '#app',
		data: {
			list: {
		        name: {
		            na: '李斯'
		        },
		        age: [[122, 34], 23, 334]
		    }
		}
	})

</script>
</html>